import allure
from typing import Dict, Any, List
from appium.webdriver.webdriver import WebDriver
from utils.assert_util.assertions import Assertions
from pages.persional_info.login_page import LoginPage
from pages.work_info.team_page import TeamPage


class AssertionExecutor:
    """断言执行器，根据测试数据执行断言"""

    def __init__(self, driver: WebDriver):
        self.driver = driver
        self.assert_that = Assertions(driver)
        self.login_steps = LoginPage(driver)
        self.home_steps = TeamPage(driver)

        # 页面定位器映射
        self.page_locators = {
            'login': self.login_steps,
            'home': self.home_steps
        }

        # 断言方法映射
        self.assertion_methods = {
            'verify_element_displayed': self.verify_element_displayed,
            'verify_element_not_displayed': self.verify_element_not_displayed,
            'verify_text_contains': self.verify_text_contains,
            'verify_text_equals': self.verify_text_equals,
            'verify_page_displayed': self.verify_page_displayed,
            'verify_element_enabled': self.verify_element_enabled,
            'verify_element_disabled': self.verify_element_disabled
        }

    def get_locator(self, page: str, locator_name: str):
        """获取定位器"""
        if not page or not locator_name:
            return None

        page_locator = self.page_locators.get(page)
        if page_locator and hasattr(page_locator, locator_name):
            return getattr(page_locator, locator_name)
        return None

    @allure.step("验证元素显示")
    def verify_element_displayed(self, validation: Dict[str, Any]):
        """验证元素显示"""
        locator = self.get_locator(validation.get('page'), validation.get('locator'))
        if not locator:
            raise ValueError(f"无法找到定位器: page={validation.get('page')}, locator={validation.get('locator')}")
        print('------------------------------------------------------------------------------')
        print(locator)
        element = self.driver.find_element(*locator)
        self.assert_that.assert_element_displayed(element, validation.get('message', '元素应该显示'))


    @allure.step("验证元素不显示")
    def verify_element_not_displayed(self, validation: Dict[str, Any]):
        """验证元素不显示"""
        locator = self.get_locator(validation.get('page'), validation.get('locator'))
        if not locator:
            raise ValueError(f"无法找到定位器: page={validation.get('page')}, locator={validation.get('locator')}")

        try:
            element = self.driver.find_element(*locator)
            self.assert_that.assert_element_not_displayed(element, validation.get('message', '元素不应该显示'))
        except:
            # 如果元素找不到，也算是不显示
            pass

    @allure.step("验证文本包含")
    def verify_text_contains(self, validation: Dict[str, Any]):
        """验证文本包含指定内容"""
        locator = self.get_locator(validation.get('page'), validation.get('locator'))
        if not locator:
            raise ValueError(f"无法找到定位器: page={validation.get('page')}, locator={validation.get('locator')}")

        element = self.driver.find_element(*locator)
        actual_text = element.text
        expected_text = validation.get('expected_text', '')

        self.assert_that.assert_contains(
            actual_text, expected_text,
            validation.get('message', f"文本应该包含 '{expected_text}'")
        )

    @allure.step("验证文本等于")
    def verify_text_equals(self, validation: Dict[str, Any]):
        """验证文本等于指定内容"""
        locator = self.get_locator(validation.get('page'), validation.get('locator'))
        if not locator:
            raise ValueError(f"无法找到定位器: page={validation.get('page')}, locator={validation.get('locator')}")

        element = self.driver.find_element(*locator)
        actual_text = element.text
        expected_text = validation.get('expected_text', '')

        self.assert_that.assert_equal(
            actual_text, expected_text,
            validation.get('message', f"文本应该等于 '{expected_text}'")
        )

    @allure.step("验证页面显示")
    def verify_page_displayed(self, validation: Dict[str, Any]):
        """验证页面显示"""
        page = validation.get('page')
        if page == 'login':
            is_displayed = self.login_steps.is_login_page_displayed()
        elif page == 'home':
            is_displayed = self.home_steps.is_welcome_displayed()
        else:
            raise ValueError(f"不支持的页面类型: {page}")

        self.assert_that.assert_true(
            is_displayed,
            validation.get('message', f"{page}页面应该显示")
        )

    @allure.step("验证元素可用")
    def verify_element_enabled(self, validation: Dict[str, Any]):
        """验证元素可用"""
        locator = self.get_locator(validation.get('page'), validation.get('locator'))
        if not locator:
            raise ValueError(f"无法找到定位器: page={validation.get('page')}, locator={validation.get('locator')}")

        element = self.driver.find_element(*locator)
        self.assert_that.assert_element_enabled(element, validation.get('message', '元素应该可用'))

    @allure.step("验证元素不可用")
    def verify_element_disabled(self, validation: Dict[str, Any]):
        """验证元素不可用"""
        locator = self.get_locator(validation.get('page'), validation.get('locator'))
        if not locator:
            raise ValueError(f"无法找到定位器: page={validation.get('page')}, locator={validation.get('locator')}")

        element = self.driver.find_element(*locator)
        self.assert_that.assert_element_disabled(element, validation.get('message', '元素应该不可用'))

    def execute_validations(self, validations: List[Dict[str, Any]]):
        """执行验证列表"""
        for validation in validations:
            action = validation.get('action')
            method = self.assertion_methods.get(action)

            if not method:
                raise ValueError(f"不支持的验证动作: {action}")

            # 执行验证方法
            method(validation)

    def execute_test_case_assertions(self, test_data: Dict[str, Any]):
        """执行测试用例的所有断言"""
        assertions = test_data.get('assertions', {})
        validations = assertions.get('validations', [])

        with allure.step(f"执行验证: {test_data.get('description', '未知测试')}"):
            self.execute_validations(validations)